<?php

namespace Frieza\Modules\PointShop\Controllers;

use App\Admin\Extensions\Tools\UserButton;
use App\Exceptions\InputErrorException;
use App\Pockets\GridDataModel as pGridDataModel;
use Biz\pockets\excel\DownExcel;
use Doraemon\model\PointShop\GoodsBaseInfo;
use Doraemon\model\PointShop\GoodsExchangeCode as mGoodsExchangeCode;
use Doraemon\model\PointShop\GoodsExtendInfo;
use Doraemon\model\PointShop\GoodsBaseInfo as mGoodsBaseInfo;
use Doraemon\model\Position\PositionRules;
use Doraemon\pockets\excel\ReadExcel;
use Doraemon\service\PointShop\GoodsBaseInfo as sGoodsBasInfo;
use Doraemon\service\PointShop\GoodsExchangeCode;
use Doraemon\service\PointShop\GoodsExtendInfo as sGoodsExtendInfo;
use Doraemon\service\position\AdmOperationModule;
use Doraemon\service\position\UserProfileModule;
use Doraemon\service\SearchOp\Schedule;
use Doraemon\tools\Crypt;
use Doraemon\tools\Hhzurl;
use Doraemon\tools\ImgUrl;
use Doraemon\tools\Log;
use Encore\Admin\Facades\Admin;
use Encore\Admin\Grid;
use Encore\Admin\Widgets\Form;
use Encore\Admin\Layout\Content;
use Illuminate\Http\Request;
use Illuminate\Support\MessageBag;
use function vierbergenlars\SemVer\Application\SemVer\help;

class GoodsBaseInfoController
{
    public function index(Content $content, Request $request)
    {
        $brand = mGoodsBaseInfo::BRAND_MAP;
        $statusArr = mGoodsBaseInfo::STATUS_MAP;
        $params = $request->all();
        $where = $this->buildWhere($params);
        $page = $request->input('page', 1);
        $pageSize = $request->input('per_page', 20);
        $limit = [($page - 1) * $pageSize, $pageSize];
        $list = sGoodsBasInfo::getList($where, $limit);
        $list = $this->format($list);
        $gridModel = new pGridDataModel($list['data'], $list['total'], [
            'perPage' => $pageSize,
            'keyName' => 'goods_id'
        ]);
        $listGrid = Admin::grid($gridModel, function (Grid $grid) use ($brand, $statusArr, $page,$pageSize) {
            $grid->disableExport();
            $grid->disableRowSelector();
            $grid->disableCreateButton();
            $grid->expandFilter();

            $grid->tools(function (Grid\Tools $tool) {
                $tool->append(new UserButton(UserButton::TYPE_HREF, 'create', '新增'));
            });

            $grid->filter(function (Grid\Filter $filter) use ($brand, $statusArr) {
                $filter->disableIdFilter();
                $filter->expand();
                $filter->column(1 / 2, function ($filter) use ($brand) {
                    $filter->equal('title', '商品名称');
                    $filter->equal('brand_id', '商品品牌')->select($brand);
                    $filter->between('addtime', '发布时间')->datetime();
                });
                $filter->column(1 / 2, function ($filter) use ($statusArr) {
                    $filter->between('point_price', '积分价格区间');
                    $filter->equal('status', '商品状态')->select($statusArr);
                    $filter->between('stock', '库存区间');
                });
            });

            $grid->column('goods_id', 'ID');
            $grid->column('cover_list', '图片')->image($this->cover_list, 100);
            $grid->column('title', '商品名称')->width(200);
            $grid->column('status', '展示状态')->display(function ($released) {
                return mGoodsBaseInfo::STATUS_MAP[$released];
            })->label([0 => 'danger', 1 => 'success']);
            $grid->column('brand_id', '商品品牌')->display(function ($released) {
                return mGoodsBaseInfo::BRAND_MAP[$released];
            });
            $grid->column('point_price', '积分价格');
            $grid->column('price', '零售价格（元）');
            $grid->column('stock', '库存')->editable();
            $url = Hhzurl::getDomain();
            Admin::script($this->setScript($url));
            $grid->actions(function ($actions)use ($page,$pageSize) {
                $actions->row->setKeyName('id');
                $actions->disableDelete();
                // 去掉编辑
                $actions->disableEdit();
                // 去掉查看
                $actions->disableView();
                $judgmentBasis = GoodsBaseInfoController::judgmentBasis($actions->row);
                $actions->prepend('<a class="grid-preview"  data-goods_id="' . $actions->row->goods_id . '"> 预览 </a>');
                $actions->prepend("<a href='pointShop/edit/{$actions->row->goods_id}?page={$page}&per_page={$pageSize}'> 编辑 </a>");
                $actions->prepend('<a class="setStatus" data-status="' . $judgmentBasis['status']['value'] . '" data-id="' . $actions->row->goods_id . '" data-title="' . '商品' . $actions->row->title . '" href="javascript:void(0);">' . $judgmentBasis['status']['desc'] . '</a>');
            });
        });
        return $content
            ->header('积分商城 商品列表')
            ->breadcrumb(['text' => '积分商城 商品列表', 'url' => ''])
            ->body($listGrid);
    }

    public function buildWhere($params)
    {
        $where = [];
        if ($params['title']) {
            $where['title[~]'] = $params['title'];
        }
        if (ctype_digit($params['brand_id'])) {
            $where['brand_id'] = $params['brand_id'];
        }
        $pointPrice = $params['point_price'];
        if (ctype_digit($pointPrice['start']) && ctype_digit($pointPrice['end'])) {
            $where['AND']['point_price[<>]'] = [$pointPrice['start'], $pointPrice['end']];
        }
        $stock = $params['stock'];
        if (ctype_digit($stock['start']) && ctype_digit($stock['end'])) {
            $where['AND']['stock[<>]'] = [$stock['start'], $stock['end']];
        }
        $addTime = $params['addtime'];
        if ($addTime['start'] && $addTime['end']) {
            $where['AND']['addtime[<>]'] = [strtotime($addTime['start']), strtotime($addTime['end'])];
        }
        if (ctype_digit($params['status'])) {
            $where['AND']['status'] = $params['status'];
        }
        return $where;
    }

    public function create(Content $content, Request $request, $goodsId = 0)
    {
        $goodsInfo = [];
        $page = 1;
        $perPage = 20;
        $goodsInfo['exchange_rule_type'] = 1;
        if ($goodsId) {
            $page = $request->input('page', 1);
            $perPage = $request->input('per_page', 20);
            $goodsInfo = sGoodsBasInfo::getInfo(['goods_id' => $goodsId]);
            $coverList = json_decode($goodsInfo['cover_list'], true);
            $goodsInfo['cover_list'] = implode(',', $coverList);
            $goodsInfo['show_time'] = date('Y-m-d H:i:s', $goodsInfo['show_time']);
            $goodsInfo['wait_time'] = date('Y-m-d H:i:s', $goodsInfo['wait_time']);
            $extendInfo = sGoodsExtendInfo::getExtendInfo(['goods_id' => $goodsId]);
            $detailList = json_decode($extendInfo['detail_list'], true);
            $detailList = array_column($detailList, 'detail_url');
            $goodsInfo['detail_list'] = implode(',', $detailList);
            $goodsInfo['exchange_rule'] = $extendInfo['exchange_rule'];
            $goodsInfo['sku_code'] = $extendInfo['sku_code'];
            $goodsInfo['exchange_rule_type'] = $extendInfo['exchange_rule_type'];
            $goodsInfo['user_profile'] = AdmOperationModule::getPositionRulesById($goodsId, PositionRules::MODULE_TYPE_POINT_SHOP, true) ?: [];
        }
        $form = new Form($goodsInfo);
        $form->fieldset('1.基本信息', function (Form $form) use ($page, $perPage, $goodsId, $goodsInfo) {
            $brand = $form->select('brand_id', '商品品牌')
                ->when('=', mGoodsBaseInfo::BRAND_VIRTUAL, function (Form $form) use ($goodsId) {
                    if (empty($goodsId)) {
                        $form->html('<div class="btn-group pull-left">
                <a  class="btn btn-info pull-right" href="/admin/pointShop/downTemplate" target="_blank">模板下载</a>
            </div>');
                        $form->file('code', '批量导入')->removable()->help('请严格按照模板格式');
                    }
                })->options(mGoodsBaseInfo::BRAND_MAP);
            if ($goodsId && $goodsInfo['brand_id'] == mGoodsBaseInfo::BRAND_VIRTUAL) {
                $brand->readOnly();
                $form->html('<span style="color: #646367">!!!虚拟商品不支持切换品牌类型</span>');
            }
            $form->hidden('goods_id', '圈子id');
            $form->hidden('status', '状态');
            $form->hidden('page', '页码')->default($page);
            $form->hidden('per_page', '每页的数量')->default($perPage);
            $form->text('title', '商品名称')->required()->placeholder('请填写商品名称')
                ->help('请正确填写商品名称，（最多50个字）');
            $form->text('sku_code', 'SKU编码')->placeholder('请填写SKU编码');
            $form->imgUpload('cover_list', '商品主图', true)
                ->showRemove(false)
                ->help('主图为3张图片；图片大小不超过200k，图片为正方形，格式为jpg或png');
        });
        $form->fieldset('2.商品详情', function (Form $form) {
            $form->imgUpload('detail_list', '商品详情', true)
                ->showRemove(false)
                ->help('最多上传8张图片；图片大小不超过2M，格式为jpg或png');
        });
        $form->fieldset('3.商品价格', function (Form $form) {
            $form->decimal('price', '零售价格（元）')
                ->required()->default(0);
            $form->decimal('cost_price', '成本价')->required()->default(0);
            $form->number('point_price', '积分价格（积分）')->placeholder(' ')->required()->min(0);
            $form->number('discount_price', '折扣价（积分）')->placeholder(' ')->min(0);
        });

        //修改虚拟商品时忽略库存的修改
        if ($goodsId && $goodsInfo['brand_id'] == mGoodsBaseInfo::BRAND_VIRTUAL) {
            $form->fieldset('4.商品库存', function (Form $form) {
                $form->hidden('stock', '商品库存（件）');
            });
        } else {
            $form->fieldset('4.商品库存', function (Form $form) {
                $form->number('stock', '商品库存（件）')->placeholder(' ')->min(0);
            });
        }

        $form->fieldset('5.其他', function (Form $form) {
            $form->radio('exchange_rule_type', '规则说明')
                ->options([
                    1 => '模板A',
                ])->when(1, function (Form $form) {
                    $form->textarea('exchange_rule_type_comtent', '内容')->readonly()->default(GoodsExtendInfo::EXCHANGE_RULE_MAP[1])->rows(12);
                });
            $form->number('sort', ' 排序权重')->placeholder(' ')->required()->min(0)->default(99);
            $form->datetime('show_time', '上架时间')->default(date('Y-m-d H:i:s'))->help('显示1970-01-01表示不设置此选项');
            $form->datetime('wait_time', '预热时间')->default(date('Y-m-d H:i:s',0))->help('显示1970-01-01表示不设置此选项');
            $form->radio('is_test', '是否是测试商品')->options([mGoodsBaseInfo::NOT_TEST => '否', mGoodsBaseInfo::IS_TEST => '是'])->default(0);
            $form->userProfile('user_profile', '用户分群')
                ->options()
                ->generate();
        });

        Admin::script($this->saveScript());
        $form->disableSubmit();
        $form->disableReset();
        $form->html('<div style="text-align:center;padding-top: 40px" >
                    <input class="btn btn-sm btn-success button-1134271147" type="submit" id="goods_save" value="保存" style="margin-right: 100px;width: 100px;height: 40px">  
                    <input class="btn btn-sm btn-dropbox 617f7e86dadff-filter-btn active" type="submit" id="goods_save_status" value="保存并上架" style="width: 100px;height: 40px"></div> ');
        $form->action('/admin/pointShop/save/');
        return $content->header('商品编辑')
            ->breadcrumb(['text' => '商品管理', 'url' => 'circle'], ['text' => '商品编辑'])
            ->row($form->render());
    }

    /**
     * @throws InputErrorException
     */
    public function save(Request $request)
    {
        $params = $request->all();
        $params = $this->checkGoodsInfo($params);
        //改为事务提交
        $adminId = Admin::user()->id;

        $goodsId = GoodsBaseInfo::action(function () use ($params, $adminId, $request) {
            $codeResult = 1;
            $goodsId = sGoodsBasInfo::save($params['goods_id'], $params, $adminId);
            $extendInfo = sGoodsExtendInfo::save($goodsId, $params, $adminId);
            //用户分群
            $userProfile = $request->input('user_profile', []);
            AdmOperationModule::addUserProfile($goodsId, $userProfile, PositionRules::MODULE_TYPE_POINT_SHOP);
            //虚拟商品
            if ($params['code_data']) {
                $codeData = $params['code_data'];
                $codeGoodsId = ['goods_id' => $goodsId];
                array_walk($codeData, function (&$value, $key, $codeGoodsId) {
                    $value = array_merge($value, $codeGoodsId);
                }, $codeGoodsId);
                $codeResult = mGoodsExchangeCode::add($codeData);
            }
            Log::info('商品修改状态', ['主商品' => $goodsId, '附属信息' => $extendInfo, 'code信息' => $codeResult]);
            return $goodsId && $extendInfo && $codeResult;
        });

        if (empty($goodsId)) {
            $error = new MessageBag(['title' => '保存失败，请重试']);
            return back()->with(compact('error'))->withInput();
        }

        $message = isset($params['save_status']) ? '商品已保存,并且上架' : '商品已保存';
        $success = new MessageBag(['title' => $message]);
        return redirect("/admin/pointShop?page={$params['page']}&per_page={$params['per_page']}")->with(compact('success'));
    }

    /**
     * 校验商品基础信息
     *
     * @param $params
     * @return \Illuminate\Http\RedirectResponse
     * @throws InputErrorException
     */
    public function checkGoodsInfo($params)
    {
        if (empty($params['brand_id'])) {
            throw new InputErrorException('请选择商品品牌', InputErrorException::DEFAULT_CODE, 'brand_id');
        }
        if (empty($params['title']) || mb_strlen($params['title']) > 50) {
            throw new InputErrorException('请填写正确的商品名称', InputErrorException::DEFAULT_CODE, 'title');
        }
        if (!ctype_digit($params['price']) && !(is_numeric($params['price']))) {
            throw new InputErrorException('请填写正确的零售价格', InputErrorException::DEFAULT_CODE, 'price');
        }
        if (!ctype_digit($params['point_price'])) {
            throw new InputErrorException('请填写正确的积分价格', InputErrorException::DEFAULT_CODE, 'point_price');
        }
        if ($params['discount_price'] && $params['discount_price'] >= $params['point_price']) {
            throw new InputErrorException('折扣价应小于原价', InputErrorException::DEFAULT_CODE, 'discount_price');
        }
        //虚拟添加兑换码
        $params['code_data'] = [];
        if ($params['brand_id'] == GoodsBaseInfo::BRAND_VIRTUAL && empty($params['goods_id'])) {
            $newFile = 'goods-code-' . date('YmdHis') . mt_rand(0, 999) . '.xls';
            $newFilePath = '/tmp' . '/' . $newFile;
            $rs = move_uploaded_file($params['code'], $newFilePath);
            if (!$rs) {
                $error = new MessageBag([
                    'title' => '文件保存失败'
                ]);
                return back()->with(compact('error'));
            }
            $excel = new ReadExcel($newFile);
            $excelData = $excel->getExcelDataNoHeader($newFilePath);
            $excelKeyArray = ['code'];
            $iMax = count($excelData);
            for ($i = 1; $i < $iMax; $i++) {
                $excelData[$i] = array_slice($excelData[$i], 0, count($excelKeyArray));
                $singleData = array_combine($excelKeyArray, $excelData[$i]);
                if (!empty($singleData['code'])) {
                    $code = Crypt::encryptByCard($singleData['code']);
                    $codeData[] = ['code' => $code, 'add_time' => time()];
                }
            }
            if (empty($codeData)) {
                throw new InputErrorException('兑换码数据为空', InputErrorException::DEFAULT_CODE, 'code');
            }
            $params['code_data'] = $codeData;
            $params['stock'] = (string)count($codeData);
        }
        if (!ctype_digit($params['stock'])) {
            throw new InputErrorException('请填写库存数量', InputErrorException::DEFAULT_CODE, 'stock');
        }
        if (empty($params['cover_list'])) {
            throw new InputErrorException('请选择主图图片', InputErrorException::DEFAULT_CODE, 'cover_list');
        }
        if (empty($params['detail_list'])) {
            throw new InputErrorException('请选择详情图片', InputErrorException::DEFAULT_CODE, 'detail_list');
        }
        if (!ctype_digit($params['sort'])) {
            throw new InputErrorException('请填写正确的序号', InputErrorException::DEFAULT_CODE, 'sort');
        }
        if (!empty($params['sku_code'])) {
            $params['sku_code'] = trim($params['sku_code']);
            $where['sku_code'] = $params['sku_code'];
            if (!empty($params['goods_id'])) {
                $where['goods_id[!]'] = $params['goods_id'];
            }
            $exist = sGoodsExtendInfo::getExtendInfo($where);
            if (!empty($exist)) {
                throw new InputErrorException('该SKU编码已存在', InputErrorException::DEFAULT_CODE, 'sku_code');
            }
        }

        if (!empty($params['wait_time'])) {
            if (empty($params['show_time'])) {
                throw new InputErrorException('请注意填写上架时间', InputErrorException::DEFAULT_CODE, 'show_time');
            }
            if ($params['show_time'] < $params['wait_time']) {
                throw new InputErrorException('预热时间需要小于上架时间', InputErrorException::DEFAULT_CODE, 'wait_time');
            }
        }
        return $params;
    }

    public function changeAttr(Request $request, $goods_id)
    {
        $param = $request->all();
        if ($param['name'] == 'stock' && !ctype_digit($param['value'])) {
            return response()->json(['errors' => ['请输入正确的库存数值']], 422);
        }
        $info = sGoodsBasInfo::getInfo(['goods_id' => $goods_id]);
        //虚拟商品不支持修改库存
        if ($info['brand_id'] == mGoodsBaseInfo::BRAND_VIRTUAL) {
            return response()->json(['errors' => ['修改失败，虚拟商品不允许修改库存']], 423);
        }
        $data = [$param['name'] => $param['value']];
        $result = sGoodsBasInfo::updateGoodsInfo($goods_id, $data, Admin::user()->id);
        if (empty($result)) {
            return response()->json(['errors' => ['修改失败，请重试']], 424);
        }
        return response()->json(['status' => true, 'message' => '修改成功']);
    }

    public function format($list)
    {
        foreach ($list['data'] as &$val) {
            $coverList = json_decode($val['cover_list'], true);
            $val['cover_list'] = ImgUrl::getUrl(ImgUrl::APPTYPE_OP, $coverList[0], ImgUrl::IMAGE_SIZE_OP_ORI);
            $val['price'] = bcdiv($val['price'], 100, 2);
        }
        return $list;
    }

    public static function judgmentBasis($data)
    {
        $result = [];
        if (isset($data['status'])) {
            $result['status']['value'] = $data['status'] == 0 ? 1 : 0;
            $result['status']['desc'] = mGoodsBaseInfo::STATUS_MAP[$result['status']['value']];
        }
        return $result;
    }

    public function setScript($url)
    {
        return <<<SCRIPT
         $('.setStatus').unbind('click').click(function() {
            var id = $(this).attr('data-id');
            var status = $(this).attr('data-status');
            var that = $(this)
            let url = '/admin/pointShop/operation/'+ id;
            let params = {
                status:status,
            };
            swal({
                title: "确定"+$(this).text()+$(this).attr('data-title')+"么？",
                type: "warning",
                showCancelButton: true,
                confirmButtonColor: "#DD6B55",
                confirmButtonText: "确认",
                showLoaderOnConfirm: true,
                cancelButtonText: "取消",
                preConfirm: function() {
                   $.post(url, params , function (result) {  
                         if (result.code == 1){
                            that.attr('data-status',status == 1 ?0:1)
                            if(status == 1){
                                that.text('下架')
                                that.parent("td").siblings(".column-status").find("span").text('上架').addClass('label-success').removeClass("label-danger")
                            } else {
                                that.text('上架')
                                that.parent("td").siblings(".column-status").find("span").text('下架').removeClass('label-success').addClass("label-danger")
                            }
                            layer.msg(result.msg);
                        } else {
                            layer.msg(result.msg);
                        }
                    });
                }
            });
        });
        $('.grid-preview').unbind('click').click(function() {
            var goods_id = $(this).attr('data-goods_id');
            var url = '{$url}/community/points-mall/goods-detail?is_preview=1&goods_id='+goods_id
            layer.open({
                type: 2,
                title: '搜索结果',
                shadeClose: true,
                shade: 0,
                maxmin: true,
                area: ['400px', '700px'],
                content: url,
            });
		});
SCRIPT;
    }

    public function saveScript()
    {
        return <<<SCRIPT
         $('#goods_save').unbind('click').click(function(){
           $(".status").attr("value",'0');
          
         });
         $('#goods_save_status').unbind('click').click(function(){
           $(".status").attr("value",'1');
         
         });
        SCRIPT;
    }

    public function operation(Request $request, $goods_id)
    {
        $param = $request->all();
        $result = ['code' => 1, 'msg' => '操作成功'];
        if (isset($param['status'])) {
            $data['status'] = $param['status'];
            if (1 == $data['status']) {//列表上架上架时间直接修改
                $data['show_time'] = 0;
            }
        }
        if (empty($data)) {
            $result = ['code' => 0, 'msg' => '请传入正确信息'];
            return response()->json($result);
        }
        $res = sGoodsBasInfo::updateGoodsInfo($goods_id, $data, Admin::user()->id);
        if (empty($res)) {
            $result = ['code' => 0, 'msg' => '操作失败，请重试'];
        }
        return response()->json($result);
    }

    public function downTemplate()
    {
        $title = '兑换码导入模板';
        $header = ['兑换码'];
        $excelObj = new DownExcel();
        $excelObj->setFileName($title);
        $excelObj->setSheetTitle($title);

        //设置列宽
        $widths = ['A' => 15, 'B' => 15];
        $excelObj->setWidth($widths);
        //默认单元格居中
        $excelObj->setDefaultStyleAlignment();
        $excelObj->freezePane('A1');//冻结窗口
        $excelObj->setTextFormat('A');
        $excelObj->create([['']], $header, null, '', [], [], [], ['A']);
    }
}